home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 10 - 1994 / 10.12 Dec 94 / ThreadedSprocket / AppSpecific / FuturesDemo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-17  |  6.3 KB  |  224 lines  |  [TEXT/MPS ]

  1. #include "FuturesDemo.h"
  2. #include "Futures.h"
  3. #include "Threads.h"
  4. #include "AEThreads.h"
  5.  
  6. #include <PPCToolBox.h>
  7. #include <EPPC.h>
  8. #include <AppleEvents.h>
  9. #include <string.h>
  10.  
  11.  
  12. AEDesc                gNullDesc;            // A null descriptor record
  13. AEAddressDesc        gSelfAddress;        // A self-addressed address descriptor record
  14. ProcessSerialNumber    gSelfPSN;            // This application's psn
  15.  
  16. #pragma segment handlers
  17.  
  18. pascal OSErr HandlePing(AppleEvent question, AppleEvent answer, long /*handlerRefcon*/)
  19. {
  20.     char*            stringPtr;
  21.     char            stringBuffer[100];
  22.     long            actualSize;
  23.     DescType        actualType;
  24.     OSErr            theErr;
  25.     EventRecord        evt;
  26.  
  27. // Beep to indicate that the question was received
  28.  
  29.     while (EventAvail(everyEvent, &evt))
  30.     {
  31.         YieldToAnyThread();
  32.     }
  33.  
  34.     SysBeep(120);
  35.  
  36. // Extract a string from the question.
  37.  
  38.     theErr = AEGetParamPtr(&question, 'qstr', 'TEXT', &actualType, (Ptr) &stringBuffer, sizeof(stringBuffer)-1, &actualSize);
  39.  
  40. // Load a string into the answer.
  41.  
  42.     stringPtr = "I’m just fine.";
  43.     theErr = AEPutParamPtr(&answer, 'rstr', 'TEXT', stringPtr, strlen(stringPtr));
  44.  
  45.     return(noErr);
  46. }
  47.  
  48. pascal OSErr HandlePing1(AppleEvent /*event*/, AppleEvent /*reply*/, long /*handlerRefcon*/)
  49. {
  50.     OSErr            theErr;
  51.     TargetID        theTargetID;
  52.     PortInfoRec        thePortInfo;
  53.     AEAddressDesc    theAddressDesc;
  54.     AppleEvent        question;
  55.     AppleEvent        answer;
  56.     char*            stringPtr;
  57.     char            stringBuffer[100];
  58.     long            actualSize;
  59.     DescType        actualType;
  60.     long            i;
  61.  
  62. // Get the target address of the other process
  63.  
  64.     theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
  65.     theTargetID.name = thePortInfo.name;
  66.     theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc);
  67.  
  68. // Start the thread that pings
  69.  
  70.     for (i=0; i<30; i++)
  71.     {
  72.         YieldToAnyThread();
  73.  
  74. // Build an AppleEvent question that is addressed to the user selected target
  75.  
  76.         theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc, kAutoGenerateReturnID, kAnyTransactionID, &question);
  77.         
  78. // Load a string into the question.
  79.  
  80.         stringPtr = "Hello server, how are you doing?";
  81.         theErr = AEPutParamPtr(&question, 'qstr', 'TEXT', stringPtr, strlen(stringPtr));
  82.  
  83. // Ask the question
  84.  
  85.         theErr = Ask(&question, &answer);
  86.  
  87. // If the answer is not a future so soon after ask, something is probably wrong.
  88.  
  89.         // if (!IsFuture(&answer)) Debugger();
  90.  
  91. // Extract a string from the answer.  This will cause the thread to block until the answer is received.
  92.  
  93.         theErr = AEGetParamPtr(&answer, 'rstr', 'TEXT', &actualType, (Ptr) &stringBuffer, sizeof(stringBuffer)-1, &actualSize);
  94.  
  95. // If the answer is still a future after retrieving a string from the answer, something is definitely wrong.
  96.  
  97.         // if (IsFuture(&answer)) Debugger();
  98.  
  99. // Dispose of the answer and the question.
  100.         
  101.         theErr = AEDisposeDesc(&answer);
  102.         theErr = AEDisposeDesc(&question);
  103.     }
  104.  
  105. // Dispose of the address descriptor now that the thread no longer needs it.
  106.  
  107.     theErr = AEDisposeDesc(&theAddressDesc);
  108.     
  109.     return theErr;
  110. }
  111.  
  112. pascal OSErr HandlePing2(AppleEvent /*event*/, AppleEvent /*reply*/, long /*handlerRefcon*/)
  113. {
  114.  
  115.     OSErr            theErr;
  116.     TargetID        theTargetID;
  117.     PortInfoRec        thePortInfo;
  118.     AEAddressDesc    theAddressDesc;
  119.     AEAddressDesc    theAddressDesc2;
  120.     AppleEvent        question;
  121.     AppleEvent        question2;
  122.     AppleEvent        answer;
  123.     AppleEvent        answer2;
  124.     long i;
  125.  
  126. // Get the target addresses of the two processes
  127.  
  128.     theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
  129.     theTargetID.name = thePortInfo.name;
  130.     theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc);
  131.  
  132.     theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
  133.     theTargetID.name = thePortInfo.name;
  134.     theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc2);
  135.  
  136. // Start the thread that pings
  137.  
  138.     for (i=0; i<30; i++)
  139.     {
  140.         YieldToAnyThread();
  141.  
  142. // Build the questions.
  143.  
  144.         theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc, kAutoGenerateReturnID, kAnyTransactionID, &question);
  145.         theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc2, kAutoGenerateReturnID, kAnyTransactionID, &question2);
  146.         
  147. // Ask the questions.
  148.  
  149.         theErr = Ask(&question, &answer);
  150.         theErr = Ask(&question2, &answer2);
  151.  
  152. // Block until the answers become real.
  153.  
  154.         theErr = BlockUntilReal(&answer);
  155.         theErr = BlockUntilReal(&answer2);
  156.  
  157. // Dispose of the answers and the questions.
  158.  
  159.         theErr = AEDisposeDesc(&answer);
  160.         theErr = AEDisposeDesc(&answer2);
  161.         theErr = AEDisposeDesc(&question);
  162.         theErr = AEDisposeDesc(&question2);
  163.     }
  164.  
  165. // Dispose of the address descriptor now that the thread no longer needs it.
  166.  
  167.     theErr = AEDisposeDesc(&theAddressDesc);
  168.     theErr = AEDisposeDesc(&theAddressDesc2);
  169.     
  170.     return noErr;
  171. }
  172.  
  173. #pragma segment Main
  174.  
  175.  
  176. void SendSimpleAEvt(AEEventClass theAEEventClass, AEEventID theAEEventID)
  177. {
  178.     AppleEvent    myAppleEvent, reply;
  179.     
  180.         //    Create the Apple Event.
  181.     AECreateAppleEvent(theAEEventClass, theAEEventID, &gSelfAddress,
  182.                                     kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
  183.         //    Send the Apple Event.
  184.       AESend(&myAppleEvent, &reply, kAENoReply, kAENormalPriority,
  185.                                     kAEDefaultTimeout, nil, nil);
  186.                                 
  187.       AEDisposeDesc(&myAppleEvent);                // Dispose of the Apple Event.
  188. }
  189.  
  190.  
  191. pascal void InitFuturesDemo(void)
  192. {
  193.      gSelfPSN.highLongOfPSN = 0;
  194.      gSelfPSN.lowLongOfPSN = kCurrentProcess;        //* Use this instead of GetCurrentProcess *//
  195.      AECreateDesc(typeProcessSerialNumber,(Ptr)&gSelfPSN,sizeof(ProcessSerialNumber),&gSelfAddress);
  196.     gNullDesc.descriptorType = typeNull;        // Initialize the global null descriptor record.
  197.     gNullDesc.dataHandle = nil;
  198.  
  199. // Initialize the futures package
  200.  
  201.     InitFutures();
  202.  
  203. // Install a handler for the ping messages in AppleEvents, so that when we receive these events, this routine will be called
  204.  
  205. #if 0
  206.     AEInstallEventHandler(kSillyEventClass, kPingEvent, NewAEEventHandlerProc(HandlePing), 0, false);
  207. #else
  208.     AEInstallThreadedEventHandler(kSillyEventClass, kPingEvent, NewAEEventHandlerProc(HandlePing), 0,
  209.                                   kCreateIfNeeded+kFPUNotNeeded, 0);
  210. #endif    
  211.     AEInstallThreadedEventHandler(kSillyEventClass, kPing1Event, NewAEEventHandlerProc(HandlePing1), 0,
  212.                                   kCreateIfNeeded+kFPUNotNeeded, 0);
  213.     AEInstallThreadedEventHandler(kSillyEventClass, kPing2Event, NewAEEventHandlerProc(HandlePing2), 0,
  214.                                   kCreateIfNeeded+kFPUNotNeeded, 0);
  215.  
  216. }
  217.  
  218.  
  219. pascal void CleanupFuturesDemo(void)
  220. {
  221.       AEDisposeDesc(&gSelfAddress);            // Dispose of my self-addressed descriptor.
  222. }
  223.  
  224.